{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:root:Setting up a new session...\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train Epoch: 0 [0/60000 (0%)]\tLoss: 2.302362\n",
      "Train Epoch: 0 [20000/60000 (33%)]\tLoss: 2.290176\n",
      "Train Epoch: 0 [40000/60000 (67%)]\tLoss: 2.249873\n",
      "\n",
      "Test set: Average loss: 0.0110, Accuracy: 4372.0/10000 (44%)\n",
      "\n",
      "Train Epoch: 1 [0/60000 (0%)]\tLoss: 2.188417\n",
      "Train Epoch: 1 [20000/60000 (33%)]\tLoss: 2.109706\n",
      "Train Epoch: 1 [40000/60000 (67%)]\tLoss: 2.010850\n",
      "\n",
      "Test set: Average loss: 0.0090, Accuracy: 5379.0/10000 (54%)\n",
      "\n",
      "Train Epoch: 2 [0/60000 (0%)]\tLoss: 1.856691\n",
      "Train Epoch: 2 [20000/60000 (33%)]\tLoss: 1.514214\n",
      "Train Epoch: 2 [40000/60000 (67%)]\tLoss: 1.369516\n",
      "\n",
      "Test set: Average loss: 0.0064, Accuracy: 7101.0/10000 (71%)\n",
      "\n",
      "Train Epoch: 3 [0/60000 (0%)]\tLoss: 1.196719\n",
      "Train Epoch: 3 [20000/60000 (33%)]\tLoss: 1.098278\n",
      "Train Epoch: 3 [40000/60000 (67%)]\tLoss: 1.031316\n",
      "\n",
      "Test set: Average loss: 0.0051, Accuracy: 7265.0/10000 (73%)\n",
      "\n",
      "Train Epoch: 4 [0/60000 (0%)]\tLoss: 1.087701\n",
      "Train Epoch: 4 [20000/60000 (33%)]\tLoss: 1.066496\n",
      "Train Epoch: 4 [40000/60000 (67%)]\tLoss: 0.933143\n",
      "\n",
      "Test set: Average loss: 0.0040, Accuracy: 7819.0/10000 (78%)\n",
      "\n",
      "Train Epoch: 5 [0/60000 (0%)]\tLoss: 0.736514\n",
      "Train Epoch: 5 [20000/60000 (33%)]\tLoss: 0.654010\n",
      "Train Epoch: 5 [40000/60000 (67%)]\tLoss: 0.716489\n",
      "\n",
      "Test set: Average loss: 0.0026, Accuracy: 8622.0/10000 (86%)\n",
      "\n",
      "Train Epoch: 6 [0/60000 (0%)]\tLoss: 0.503302\n",
      "Train Epoch: 6 [20000/60000 (33%)]\tLoss: 0.553055\n",
      "Train Epoch: 6 [40000/60000 (67%)]\tLoss: 0.528475\n",
      "\n",
      "Test set: Average loss: 0.0022, Accuracy: 8774.0/10000 (88%)\n",
      "\n",
      "Train Epoch: 7 [0/60000 (0%)]\tLoss: 0.434903\n",
      "Train Epoch: 7 [20000/60000 (33%)]\tLoss: 0.500049\n",
      "Train Epoch: 7 [40000/60000 (67%)]\tLoss: 0.417744\n",
      "\n",
      "Test set: Average loss: 0.0020, Accuracy: 8900.0/10000 (89%)\n",
      "\n",
      "Train Epoch: 8 [0/60000 (0%)]\tLoss: 0.483102\n",
      "Train Epoch: 8 [20000/60000 (33%)]\tLoss: 0.403840\n",
      "Train Epoch: 8 [40000/60000 (67%)]\tLoss: 0.419145\n",
      "\n",
      "Test set: Average loss: 0.0019, Accuracy: 8964.0/10000 (90%)\n",
      "\n",
      "Train Epoch: 9 [0/60000 (0%)]\tLoss: 0.446667\n",
      "Train Epoch: 9 [20000/60000 (33%)]\tLoss: 0.318437\n",
      "Train Epoch: 9 [40000/60000 (67%)]\tLoss: 0.311085\n",
      "\n",
      "Test set: Average loss: 0.0018, Accuracy: 9011.0/10000 (90%)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import  torch\n",
    "import  torch.nn as nn\n",
    "import  torch.nn.functional as F\n",
    "import  torch.optim as optim\n",
    "from torchvision import datasets, transforms\n",
    "\n",
    "from visdom import Visdom\n",
    "\n",
    "batch_size=200\n",
    "learning_rate=0.01\n",
    "epochs=10\n",
    "\n",
    "train_loader = torch.utils.data.DataLoader(\n",
    "    datasets.MNIST('../data', train=True, download=True,\n",
    "                   transform=transforms.Compose([\n",
    "                       transforms.ToTensor(),\n",
    "                       # transforms.Normalize((0.1307,), (0.3081,))\n",
    "                   ])),\n",
    "    batch_size=batch_size, shuffle=True)\n",
    "test_loader = torch.utils.data.DataLoader(\n",
    "    datasets.MNIST('../data', train=False, transform=transforms.Compose([\n",
    "        transforms.ToTensor(),\n",
    "        # transforms.Normalize((0.1307,), (0.3081,))\n",
    "    ])),\n",
    "    batch_size=batch_size, shuffle=True)\n",
    "\n",
    "\n",
    "\n",
    "class MLP(nn.Module):\n",
    "\n",
    "    def __init__(self):\n",
    "        super(MLP, self).__init__()\n",
    "\n",
    "        self.model = nn.Sequential(\n",
    "            nn.Linear(784, 200),\n",
    "            nn.LeakyReLU(inplace=True),\n",
    "            nn.Linear(200, 200),\n",
    "            nn.LeakyReLU(inplace=True),\n",
    "            nn.Linear(200, 10),\n",
    "            nn.LeakyReLU(inplace=True),\n",
    "        )\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = self.model(x)\n",
    "        return x\n",
    "\n",
    "\n",
    "net = MLP()\n",
    "optimizer = optim.SGD(net.parameters(), lr=learning_rate)\n",
    "criteon = nn.CrossEntropyLoss()\n",
    "\n",
    "viz = Visdom()\n",
    "\n",
    "viz.line([0.], [0.], win='train_loss', opts=dict(title='train loss'))\n",
    "viz.line([[0.0, 0.0]], [0.], win='test', opts=dict(title='test loss&acc.',\n",
    "                                                   legend=['loss', 'acc.']))\n",
    "global_step = 0\n",
    "\n",
    "for epoch in range(epochs):\n",
    "\n",
    "    for batch_idx, (data, target) in enumerate(train_loader):\n",
    "        data = data.view(-1, 28*28)\n",
    "        logits = net(data)\n",
    "        loss = criteon(logits, target)\n",
    "\n",
    "        optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        # print(w1.grad.norm(), w2.grad.norm())\n",
    "        optimizer.step()\n",
    "\n",
    "        global_step += 1\n",
    "        viz.line([loss.item()], [global_step], win='train_loss', update='append')\n",
    "\n",
    "        if batch_idx % 100 == 0:\n",
    "            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n",
    "                epoch, batch_idx * len(data), len(train_loader.dataset),\n",
    "                       100. * batch_idx / len(train_loader), loss.item()))\n",
    "\n",
    "\n",
    "    test_loss = 0\n",
    "    correct = 0\n",
    "    for data, target in test_loader:\n",
    "        data = data.view(-1, 28 * 28)\n",
    "        logits = net(data)\n",
    "        test_loss += criteon(logits, target).item()\n",
    "\n",
    "        pred = logits.argmax(dim=1)\n",
    "        correct += pred.eq(target).float().sum().item()\n",
    "\n",
    "    viz.line([[test_loss, correct / len(test_loader.dataset)]],\n",
    "             [global_step], win='test', update='append')\n",
    "    viz.images(data.view(-1, 1, 28, 28), win='x')\n",
    "    viz.text(str(pred.detach().cpu().numpy()), win='pred',\n",
    "             opts=dict(title='pred'))\n",
    "\n",
    "    test_loss /= len(test_loader.dataset)\n",
    "    print('\\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n",
    "        test_loss, correct, len(test_loader.dataset),\n",
    "        100. * correct / len(test_loader.dataset)))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
